package service

import (
	"context"
	"encoding/base64"
	"fmt"
	"io/ioutil"
	"os"
	"path/filepath"
	"time"

	"github.com/chromedp/cdproto/page"
	"github.com/chromedp/chromedp"
	"github.com/go-resty/resty/v2"
	"github.com/patrickmn/go-cache"
	"github.com/sirupsen/logrus"
)

type RenderService struct {
	plantumlServer string
	cache          *cache.Cache
	logger         *logrus.Logger
	tempDir        string
	client         *resty.Client
}

func NewRenderService(plantumlServer string, logger *logrus.Logger, tempDir string) *RenderService {
	return &RenderService{
		plantumlServer: plantumlServer,
		cache:          cache.New(30*time.Minute, 10*time.Minute), // 缓存30分钟
		logger:         logger,
		tempDir:        tempDir,
		client:         resty.New().SetTimeout(30 * time.Second),
	}
}

// RenderMermaidToImage 渲染Mermaid图表为图片
func (rs *RenderService) RenderMermaidToImage(mermaidCode string, settings map[string]interface{}) (string, error) {
	// 检查缓存
	cacheKey := fmt.Sprintf("mermaid_%x", mermaidCode)
	if cached, found := rs.cache.Get(cacheKey); found {
		return cached.(string), nil
	}

	rs.logger.Infof("Rendering Mermaid chart")

	// 获取设置
	format := "png"
	if f, ok := settings["format"].(string); ok {
		format = f
	}

	dpi := 300
	if d, ok := settings["dpi"].(int); ok {
		dpi = d
	}

	// 创建HTML页面用于渲染
	htmlContent := rs.createMermaidHTML(mermaidCode, dpi)

	// 创建临时HTML文件
	tempFile := filepath.Join(rs.tempDir, fmt.Sprintf("mermaid_%d.html", time.Now().UnixNano()))
	err := ioutil.WriteFile(tempFile, []byte(htmlContent), 0644)
	if err != nil {
		return "", err
	}
	defer os.Remove(tempFile)

	// 使用chromedp渲染
	imageData, err := rs.renderHTMLToImage(tempFile, format, dpi)
	if err != nil {
		return "", err
	}

	// 转换为base64
	base64Data := base64.StdEncoding.EncodeToString(imageData)

	// 缓存结果
	rs.cache.Set(cacheKey, base64Data, cache.DefaultExpiration)

	rs.logger.Infof("Mermaid chart rendered successfully")
	return base64Data, nil
}

// RenderPlantUMLToImage 渲染PlantUML图表为图片
func (rs *RenderService) RenderPlantUMLToImage(plantumlCode string, settings map[string]interface{}) (string, error) {
	// 获取设置
	format := "png"
	if f, ok := settings["format"].(string); ok {
		format = f
	}
	
	// 获取PlantUML服务器地址，优先使用设置中的服务器
	plantumlServer := rs.plantumlServer
	if server, ok := settings["server"].(string); ok && server != "" {
		plantumlServer = server
	}

	// 检查缓存（包含服务器地址在缓存键中）
	cacheKey := fmt.Sprintf("plantuml_%s_%x", plantumlServer, plantumlCode)
	if cached, found := rs.cache.Get(cacheKey); found {
		return cached.(string), nil
	}

	rs.logger.Infof("Rendering PlantUML chart using server: %s", plantumlServer)

	// 调用PlantUML服务器
	resp, err := rs.client.R().
		SetHeader("Content-Type", "text/plain").
		SetBody(plantumlCode).
		Post(plantumlServer + "/" + format)

	if err != nil {
		return "", fmt.Errorf("failed to call PlantUML server (%s): %v", plantumlServer, err)
	}

	if resp.StatusCode() != 200 {
		return "", fmt.Errorf("PlantUML server (%s) returned status: %d", plantumlServer, resp.StatusCode())
	}

	// 转换为base64
	base64Data := base64.StdEncoding.EncodeToString(resp.Body())

	// 缓存结果
	rs.cache.Set(cacheKey, base64Data, cache.DefaultExpiration)

	rs.logger.Infof("PlantUML chart rendered successfully")
	return base64Data, nil
}

// RenderChartPreview 渲染图表预览
func (rs *RenderService) RenderChartPreview(chartType, content string, settings map[string]interface{}) (map[string]interface{}, error) {
	var imageData string
	var err error

	switch chartType {
	case "mermaid":
		imageData, err = rs.RenderMermaidToImage(content, settings)
	case "plantuml":
		imageData, err = rs.RenderPlantUMLToImage(content, settings)
	default:
		return nil, fmt.Errorf("unsupported chart type: %s", chartType)
	}

	if err != nil {
		return nil, err
	}

	// 估算文件大小
	decodedData, _ := base64.StdEncoding.DecodeString(imageData)
	fileSize := len(decodedData)

	return map[string]interface{}{
		"image":     imageData,
		"size":      fileSize,
		"format":    settings["format"],
		"dpi":       settings["dpi"],
		"timestamp": time.Now().Unix(),
	}, nil
}

// BatchRenderCharts 批量渲染图表
func (rs *RenderService) BatchRenderCharts(requests []map[string]interface{}) ([]map[string]interface{}, error) {
	results := make([]map[string]interface{}, len(requests))

	for i, req := range requests {
		chartType, _ := req["type"].(string)
		content, _ := req["content"].(string)
		settings, _ := req["settings"].(map[string]interface{})

		if settings == nil {
			settings = make(map[string]interface{})
		}

		result, err := rs.RenderChartPreview(chartType, content, settings)
		if err != nil {
			results[i] = map[string]interface{}{
				"error": err.Error(),
				"index": i,
			}
		} else {
			results[i] = result
		}
	}

	return results, nil
}

// createMermaidHTML 创建Mermaid渲染HTML
func (rs *RenderService) createMermaidHTML(mermaidCode string, dpi int) string {
	// 根据DPI调整缩放比例
	scale := float64(dpi) / 96.0 // 96 DPI是默认值

	return fmt.Sprintf(`
<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <script src="https://cdn.jsdelivr.net/npm/mermaid@10.6.1/dist/mermaid.min.js"></script>
    <style>
        body {
            margin: 0;
            padding: 20px;
            background: white;
            font-family: Arial, sans-serif;
            transform: scale(%.2f);
            transform-origin: top left;
        }
        .mermaid {
            background: white;
        }
    </style>
</head>
<body>
    <div class="mermaid">
%s
    </div>
    <script>
        mermaid.initialize({
            startOnLoad: true,
            theme: 'default',
            themeVariables: {
                primaryColor: '#fff',
                primaryTextColor: '#000',
                primaryBorderColor: '#000',
                lineColor: '#000'
            }
        });
    </script>
</body>
</html>`, scale, mermaidCode)
}

// renderHTMLToImage 将HTML渲染为图片
func (rs *RenderService) renderHTMLToImage(htmlFile, format string, dpi int) ([]byte, error) {
	// 创建Chrome上下文
	ctx, cancel := chromedp.NewContext(context.Background())
	defer cancel()

	// 设置超时
	ctx, cancel = context.WithTimeout(ctx, 30*time.Second)
	defer cancel()

	var imageData []byte

	// 渲染图片
	err := chromedp.Run(ctx,
		chromedp.Navigate("file://"+htmlFile),
		chromedp.WaitVisible(".mermaid"),
		chromedp.Sleep(2*time.Second), // 等待渲染完成
		chromedp.ActionFunc(func(ctx context.Context) error {
			var err error
			
			if format == "pdf" {
				imageData, _, err = page.PrintToPDF().
					WithPrintBackground(true).
					Do(ctx)
			} else {
				// 截图
				err = chromedp.FullScreenshot(&imageData, 95).Do(ctx)
			}
			
			return err
		}),
	)

	if err != nil {
		return nil, err
	}

	return imageData, nil
}

// GetRenderSettings 获取渲染设置选项
func (rs *RenderService) GetRenderSettings() map[string]interface{} {
	return map[string]interface{}{
		"formats": []string{"png", "jpg", "svg", "pdf"},
		"dpi_options": []int{72, 150, 300, 600},
		"themes": []string{"default", "dark", "forest", "neutral"},
		"sizes": map[string]map[string]int{
			"small":  {"width": 400, "height": 300},
			"medium": {"width": 800, "height": 600},
			"large":  {"width": 1200, "height": 900},
		},
		"plantuml_server": rs.plantumlServer,
	}
}

// ClearCache 清除渲染缓存
func (rs *RenderService) ClearCache() {
	rs.cache.Flush()
	rs.logger.Info("Render cache cleared")
}

// GetCacheStats 获取缓存统计
func (rs *RenderService) GetCacheStats() map[string]interface{} {
	return map[string]interface{}{
		"item_count": rs.cache.ItemCount(),
	}
}